using System;
using System.Collections;
using Flaschengeist.Entities;
using Flaschengeist.Views;
using Svelto.Tasks;
using UnityEngine;

namespace Flaschengeist.Views 
{
	public class LevelResultView : BaseView
	{			
		private const int boxWidth = 350;	
		private const int boxHeight = 260;	
		private const string lbl = "label";
		
		private LevelResult result;
		private float incrementSpeed = 0.01f;		
		private int correctNotesScore;
		private int relatedNotesScore;
		private int remainingFluidScore;
		private int remainingTimeScore;
		private bool incrementCompleted;
		private Texture2D header;
		private Texture2D background;
		private GUISkin skin;
		
		public void Start()
		{
			skin = (GUISkin)Resources.Load (Settings.GUI_SKIN_SMALL_TEXT);
			header = (Texture2D)Resources.Load("textures/gui_resultHeader");
			background = (Texture2D)Resources.Load("textures/gui_menuBackground");
		}
		
		public void Show(LevelResult result)
		{	
			this.result = result;			
			correctNotesScore = 0;
			relatedNotesScore = 0;
			remainingFluidScore = 0;
			remainingTimeScore = 0;
			incrementCompleted = false;
			
			var incCorrectNotesScore = new SingleTask(IncrementCorrectNotesScore(result.CorrectNotesScore),() => 
			{
				var incRelatedNotesScore = new SingleTask(IncrementSimilarNotesScore(result.SimilarNotesScore), () =>
				{					
					var incRemainingFluidScore =  new SingleTask(IncrementRemainingFluidScore(result.RemainingFluidScore), () =>
					{
						var incRemainingTimeScore =  new SingleTask(IncrementRemainingTimeScore(result.RemainingTimeScore), () =>
						{
							incrementCompleted = true;
						});
						TaskRunner.Instance.Run(incRemainingTimeScore);	
					});
					TaskRunner.Instance.Run(incRemainingFluidScore);	
				});
				TaskRunner.Instance.Run(incRelatedNotesScore);	
			});					
			TaskRunner.Instance.Run(incCorrectNotesScore);	
			
			Show();
		}
		
		public void OnGUI()
		{
			if (IsActive)
			{
				GUI.skin = skin;	
				GUI.DrawTexture(new Rect(Screen.width/2 - 163, Screen.height/2 - 115, 326, 320),background);
				GUI.DrawTexture(new Rect(Screen.width/2 - 163, Screen.height/2 - 250, 326, 198),header);
				
				//Label Korrekte Noten				
				var lblCorrectNotes = string.Format("{0} of {1} notes correctly:", result.CorrectNotes, result.LevelTrack.Length); 				
				GUI.Label (new Rect(Screen.width/2 + 70, Screen.height/2 - boxHeight/2 + 80, 250, 30), correctNotesScore.ToString());
				GUI.Label(new Rect(Screen.width/2 - 100, Screen.height/2 - boxHeight/2 + 80, 250, 30), lblCorrectNotes);
				
				//Label ähnliche Noten				
				var lblrelatedNotes = string.Format("{0} of {1} notes similar:", result.SimilarNotes, result.LevelTrack.Length); 
				GUI.Label (new Rect(Screen.width/2 + 70, Screen.height/2 - boxHeight/2 + 105, 250, 30), relatedNotesScore.ToString());
				GUI.Label(new Rect(Screen.width/2 - 100, Screen.height/2 - boxHeight/2 + 105, 250, 30), lblrelatedNotes);
				
				//Label verbleibende Flüssigkeit			
				var lblremainingFluid = string.Format("{0} ml of liquid left:", result.RemainingFluid);
				GUI.Label (new Rect(Screen.width/2 + 70, Screen.height/2 - boxHeight/2 + 130, 250, 30), remainingFluidScore.ToString());
				GUI.Label(new Rect(Screen.width/2 - 100, Screen.height/2 - boxHeight/2 + 130, 250, 30), lblremainingFluid);
							
				//Label verbleibende Zeit			
				var lblremainingTime = string.Format("{0} second(s) left:", result.RemainingTimeSec);
				GUI.Label (new Rect(Screen.width/2 + 70, Screen.height/2 - boxHeight/2 + 155, 250, 30), remainingTimeScore.ToString());
				GUI.Label(new Rect(Screen.width/2 - 100, Screen.height/2 - boxHeight/2 + 155, 250, 30), lblremainingTime);
				
				if (incrementCompleted)
				{
					//Label Gesamtscore
					GUI.Label(new Rect(Screen.width/2 - 100, Screen.height/2 - boxHeight/2 + 180, 250, 30), "Total:");
					GUI.Label(new Rect(Screen.width/2 + 70, Screen.height/2 - boxHeight/2 + 180, 250, 30), result.Score.ToString());
					GUI.Label(new Rect(Screen.width/2 - 100, Screen.height/2 - boxHeight/2 + 205, 250, 30), "Level " + (result.Passed ? "passed!" : "failed!"));
					
					//Bewertung des Level in Prozent					
					double grading = (double)result.Score / (double)result.MaxScore;
					var lblLevelGrading = string.Format("You've reached {0:P2}, ", grading); 
					
					if (grading > 0.9)
						lblLevelGrading += "well done!";
					else if (grading > 0.8)
						lblLevelGrading += "nice!";
					else if (grading > 0.6)
						lblLevelGrading += "not bad!";
					else
						lblLevelGrading += "pretty bad!";
					
					GUI.Label(new Rect(Screen.width/2 - 100, Screen.height/2 - boxHeight/2 + 230, 250, 30), lblLevelGrading);
										
					//Button Next
					if (GUI.Button(new Rect(Screen.width/2 - Settings.GUI_BUTTON_WIDTH/2, Screen.height/2 - boxHeight/2 + 280, Settings.GUI_BUTTON_WIDTH, Settings.GUI_BUTTON_HEIGHT), "next"))
					{
						Close();
					}	
				}			
			}
		}
		
		private IEnumerator IncrementSimilarNotesScore(int limit)
		{
			while(relatedNotesScore < limit)
			{				
				relatedNotesScore += 5;
				yield return new WaitForSeconds(incrementSpeed);				
			}
		}
		
		private IEnumerator IncrementCorrectNotesScore(int limit)
		{
			while(correctNotesScore < limit)
			{				
				correctNotesScore += 5;
				yield return new WaitForSeconds(incrementSpeed);				
			}
		}
		
		private IEnumerator IncrementRemainingFluidScore(int limit)
		{
			while(remainingFluidScore < limit)
			{				
				remainingFluidScore += 1;
				yield return new WaitForSeconds(incrementSpeed);				
			}
		}
				
		private IEnumerator IncrementRemainingTimeScore(int limit)
		{
			while(remainingTimeScore < limit)
			{				
				remainingTimeScore += 1;
				yield return new WaitForSeconds(incrementSpeed);				
			}
		}
		
		public event Action Close;
	}
}

